import { _decorator, Component, Node, Prefab, v2, Vec2 ,instantiate, Tween, Vec3} from 'cc';
const { ccclass, property } = _decorator;
import { Game } from './Game';
import { Player } from './Player';
import { Block } from './Block';


    // 赛道格子类型，坑（BT_NONE）或者实路（BT_STONE）
  
    enum BlockType {
        BT_NONE,
        BT_STONE,
    };


@ccclass('Stage')
export class Stage extends Component {
    @property(Player)
    private player: Player = null;



    private game: Game = null;


    @property(Prefab)
    private blockPrefab: Prefab = null; // 编辑器属性引用

     // 赛道长度
     @property
     public roadLength = 1;
     private _road: BlockType[] = [];

     private curIndex:number=0;

     private roadIndex:number=3;

     private blockList: Array<Block>; // 记录添加的Block列表




 generateRoad() {
        // 防止游戏重新开始时，赛道还是旧的赛道
        // 因此，需要移除旧赛道，清除旧赛道数据
        //this.node.removeAllChildren();
        this._road = [];
        // 确保游戏运行时，人物一定站在实路上
        this._road.push(BlockType.BT_STONE);

        // 确定好每一格赛道类型
        for (let i = 1; i < this.roadLength; i++) {
            // 如果上一格赛道是坑，那么这一格一定不能为坑
            if (this._road[i-1] === BlockType.BT_NONE) {
                this._road.push(BlockType.BT_STONE);

                
            } else {
                this._road.push(Math.floor(Math.random() * 2));
            }
        }

        // 根据赛道类型生成赛道
        for (let j = 0; j < this.roadIndex; j++) {
        //for (let j = 0; j < this._road.length; j++) {
            let block: Node = this.spawnBlockByType(this._road[j]);
            // 判断是否生成了道路，因为 spawnBlockByType 有可能返回坑（值为 null）
            if (block) {
                this.node.addChild(block);
                //block.setPosition(j*200, -195, 0);
                
                block.setPosition(j*200-400, -195, 0);
                this.blockList.push(block.getComponent(Block));
            }else{

                this.blockList.push(null);
            }
        }
    }
    spawnBlockByType(type: BlockType) {
        if (!this.blockPrefab) {
            return null;
        }

        let block: Node | null = null;
        // 赛道类型为实路才生成
        switch(type) {
            case BlockType.BT_STONE:
                block = instantiate(this.blockPrefab);
                break;
        }

        return block;
    }

    
    public init(game: Game) {
        this.game = game;
        this.blockList = [];

        this.generateRoad();

    }

    public playerJump(step: number) {


        if(!this.player.canJump){

            return;
        }
        this.curIndex=this.curIndex+step;
        this.player.index=this.curIndex;
        this.moveStage(step);
        this.player.jump(step);
        //
        
        if(this._road[this.curIndex]==BlockType.BT_NONE){
          // this.player.die();

          this.player.canJump=false;
           this.scheduleOnce(() => { // 这时还在空中，要等到落到地面在执行死亡动画
            this.player.die();
            this.game.overGame();
           
        }, 0.1);
        return;
        }

        this.game.addScore(1);

        //创建roadIndex后面两个
        let block1: Node = this.spawnBlockByType(this._road[this.roadIndex]);
        if (block1) {
            this.node.addChild(block1);
           
            block1.setPosition(this.roadIndex*200-400, -195, 0);
            this.blockList.push(block1.getComponent(Block));
            
        }
        else{
            this.blockList.push(null);
        }
        this.roadIndex=this.roadIndex+1;

        let block2: Node = this.spawnBlockByType(this._road[this.roadIndex]);
        if (block2) {
            this.node.addChild(block2);
           
            block2.setPosition((this.roadIndex)*200-400, -195, 0);
            this.blockList.push(block2.getComponent(Block));
        }else{
            this.blockList.push(null);
        }
        this.roadIndex=this.roadIndex+1;

        //前面两个掉下去
        let blockIndex = this.player.index;
        this.blockList[blockIndex].fail( () => { 

        
            if (this.player.index === blockIndex) { // 如果Block下落时玩家还在上面游戏结束
                this.player.die();
                this.game.overGame();
                this.player.canJump=false;
            }
            
        });
        



        
    }



    private moveStage(step: number) {
        //let moveAction = cc.moveBy(this.jumpDuration, cc.v2(-this.stepDistance * step, 0));

        if(this.curIndex<3){
            return;
        }

        const tw1 = new Tween(this.node)
        let x=this.node.position.x;
        let y=this.node.position.y;
        x=x-200;
        if(step==2){
            x=x-200;
        }
        tw1.to(0.01, { position: new Vec3(x, y, 0) })
        .start();


       // this.node.runAction(moveAction);
       // for (let i = 0; i < step; i++) {
       //     this.randomAddBlock();
        //}
    }



}

